﻿using Model;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.SessionState;
using Newtonsoft.Json;
using Dal;
namespace Web.service
{

    public class MyDateTimeConverter : Newtonsoft.Json.JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            if(objectType ==typeof(DateTime))
            {
                return true;
            }
            return false;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var dt = (DateTime)value;
            if(dt != DateTime.MinValue)
            {
                writer.WriteValue(dt.ToString("yyyy-MM-dd HH:mm:ss"));
            }
            else
            {
                writer.WriteValue("");
            }

        }
    }



    /// <summary>
    /// BaseService 的摘要说明
    /// 其他的Server可以继承该类,
    /// 就可以通过action=方法名的方式来调用方法了
    /// 默认void的方法会输出{success:true}
    /// 有返回值的方法如果返回了null,则不输出任何东西,不为null,则序列化成json对象输出
    /// </summary>
    public abstract class BaseService<T> : IHttpHandler, IRequiresSessionState where T : new()
    {
        protected log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public void ProcessRequest(HttpContext context)
        {
            Object result = null;
            try
            {
                var action = context.Request.Params["action"];
                Type curType = GetType();

                MethodInfo method = curType.GetMethod(action, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                result = method.Invoke(this, new object[] { HttpContext.Current });
                if (result == null && method.ReturnType == typeof(void))
                {
                    result = new { success = true };
                }

            }
            catch(HttpRequestValidationException ex)
            {
                var r = new Dictionary<string, object>();
                r.Add("success", false);
                r.Add("error", true);
                r.Add("msg", "输入的字符串不能包含危险字符串,例如尖括号");
                result = r;
            }
            catch (Exception e)
            {
              

                var r = new Dictionary<string, object>();
                r.Add("success", false);
                r.Add("error", true);
                if (e.InnerException != null)
                {
                    Exception ex = e.InnerException;
                    if(ex is IException)
                    {
                        r.Add("msg", ex.Message);
                        Log.Debug(ex);
                    }
                    else
                    {
                        r.Add("msg", "系统错误:"+ex.Message);
                        Log.Error(ex);
                    }
                }
                else
                {
                    Log.Debug("未实现的方法:" + context.Request["action"]);
                    r.Add("msg", "该功能尚未实现,请联系有关人员解决");
                }
                result = r;
            }
            if (result != null)
            {
                context.Response.ContentType = "text/json";

                String str = Newtonsoft.Json.JsonConvert.SerializeObject(result,new MyDateTimeConverter());
                context.Response.Write(str);
              //  context.Response.Write(_jss.Serialize(result));

            }
        }

        protected PageInfo<T> requestPageInfo(HttpContext context)
        {
            PageInfo<T> pi = new PageInfo<T>();
            pi.page = int.Parse(context.Request["page"] ?? "1");
            pi.rows = int.Parse(context.Request["rows"] ?? "20");
            pi.query = requestBean(context);
            String tmp = context.Request["startTime"];
            if (!string.IsNullOrEmpty(tmp))
            {
                pi.startTime = DateTime.Parse(tmp);
            }
            tmp = context.Request["endTime"];
            if (!string.IsNullOrEmpty(tmp))
            {
                pi.endTime = DateTime.Parse(tmp);
            }
            return pi;
        }

        /// <summary>
        /// 获取json形式提交的model对象
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected T requestModel(HttpContext context)
        {
            return requestModel(context, "model");
        }
        protected T requestModel(HttpContext context, String pro)
        {
            String modelStr = context.Request[pro];
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(modelStr);
        }

        //protected QueryPageInfo requestQueryPageInfo(HttpContext context)
        //{
        //    QueryPageInfo info = new QueryPageInfo()
        //    {
        //        page = int.Parse(context.Request["page"] ?? "1"),
        //        rows = int.Parse(context.Request["rows"] ?? "20")
        //};

        //    Type type = typeof(T);
        //    PropertyInfo[] pis = type.GetProperties();
        //    foreach (PropertyInfo pi in pis)
        //    {
        //        string name = pi.Name;
        //        Type pType = pi.PropertyType;

        //        var ts = new Object[]
        //        {
        //            typeof(String),
        //            typeof(int),
        //            typeof(int?),
        //            typeof(long),
        //            typeof(long?),
        //            typeof(bool),
        //            typeof(bool?)
        //        };
        //        if (ts.Contains(pType))
        //        {
        //            string valuestr = context.Request[name];
        //            if (!String.IsNullOrEmpty(valuestr))
        //            {
        //                String t = "eq";
        //                if (pType.Equals(typeof(String)))
        //                {
        //                    t = "like";
        //                    valuestr = "%" + valuestr + "%";
        //                }
        //                info.queryEles.Add(new QueryEle()
        //                {
        //                    type = t,
        //                    name = name,
        //                    objs = new Object[] { valuestr }
        //                });
        //            }
        //        }

        //    }
        //    return info;
        //}


        protected void requestWhere(HttpContext context,StringBuilder where,List<Object> paramValues,int c,String tbname)
        {
            Type type = typeof(T);
            PropertyInfo[] pis = type.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                string name = pi.Name;
                Type pType = pi.PropertyType;

                if (pType.Equals(typeof(String)))
                {
                    string valuestr = context.Request[name];
                    if (valuestr != null)
                    {
                        where.Append(" and " + tbname + "." + name + " like {" + c++ +"}");
                        paramValues.Add("%" + valuestr + "%");
                    }
                }
                else if (pType.Equals(typeof(int?)) || pType.Equals(typeof(int)))
                {
                    var valueintstr = context.Request[name];
                    if (!string.IsNullOrEmpty(valueintstr))
                    {
                        where.Append(" and " + tbname + "." + name + " = {" + c++ + "}");
                        paramValues.Add(int.Parse(valueintstr));
                    }
                }
                else if (pType.Equals(typeof(long?)) || pType.Equals(typeof(long)))
                {
                    var valuelongstr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuelongstr))
                    {
                        where.Append(" and " + tbname + "." + name + " = {" + c++ + "}");
                        paramValues.Add(long.Parse(valuelongstr));
                    }
                }

                else if (pi.PropertyType.Equals(typeof(DateTime?)) || pi.PropertyType.Equals(typeof(DateTime)))
                {
                    string valuestr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuestr))
                    {
                        where.Append(" and " + tbname + "." + name + " ={" + c++ +"}");
                        paramValues.Add(DateTime.Parse(valuestr));
                    }
                }
                else if (pi.PropertyType.Equals(typeof(bool?)) || pi.PropertyType.Equals(typeof(bool)))
                {
                    string valuestr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuestr))
                    {
                        where.Append(" and " + tbname + "." + name + " ={" + c++ + "}");
                        paramValues.Add(bool.Parse(valuestr));
                    }
                }
             }
         }


        /// <summary>
        /// 返回当前表单里面的bean
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected T requestBean(HttpContext context)
        {
            T bean = Activator.CreateInstance<T>();
            Type type = typeof(T);
            PropertyInfo[] pis = type.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                string name = pi.Name;
                Type pType = pi.PropertyType;

                if (pType.Equals(typeof(String)))
                {
                   // var a = 
                    string valuestr = context.Request.Form[name]; 
                    if (valuestr != null)
                    {
                        pi.SetValue(bean, valuestr, null);
                    }
                }
                else if (pType.Equals(typeof(int?)) || pType.Equals(typeof(int)))
                {
                    var valueintstr = context.Request[name];
                    if (!string.IsNullOrEmpty(valueintstr))
                    {
                        pi.SetValue(bean, int.Parse(valueintstr), null);
                    }
                }
                else if (pType.Equals(typeof(long?)) || pType.Equals(typeof(long)))
                {
                    var valuelongstr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuelongstr))
                    {
                        pi.SetValue(bean, long.Parse(valuelongstr), null);
                    }
                }

                else if (pi.PropertyType.Equals(typeof(DateTime?)) || pi.PropertyType.Equals(typeof(DateTime)))
                {
                    string valuestr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuestr))
                    {
                        pi.SetValue(bean, DateTime.Parse(valuestr), null);
                    }
                }
                else if (pi.PropertyType.Equals(typeof(bool?)) || pi.PropertyType.Equals(typeof(bool)))
                {
                    string valuestr = context.Request[name];
                    if (!string.IsNullOrEmpty(valuestr))
                    {
                        pi.SetValue(bean, bool.Parse(valuestr), null);
                    }
                }

            }

            return bean;
        }
        [Obsolete("方法已被弃用,请改用新方案", false)]
        protected T RequestBean(HttpContext context)
        {
            return requestBean(context);
        }


        /// <summary>
        /// 从session中获取用户,如果没有则返回null
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected UserModel GetSessionUser(HttpContext context)
        {

            string[] keys = context.Request.Cookies.AllKeys;
            var cs = context.Response.Cookies;
            var cs2 = context.Request.Cookies;

            if (context.Session["user"] == null)
            {
                UserModel user = null;
                try
                {
                    String username = context.Request.Cookies["username"].Value;
                    String password = context.Request.Cookies["password"].Value;
                    user = new UserDal().Login(username, password);
                    SetSessionUser(context, user);
                }catch(Exception ex)
                {
                    Log.Debug(ex);
                }
                return user;
            }
            else
            {
                return (UserModel)context.Session["user"];
            }
        }
        protected UserModel GetSessionUserIfNotExistThrow(HttpContext context)
        {
            if (context.Session["user"] == null)
            {
                UserModel user = null;
                try
                {
                    String username = context.Request.Cookies["username"].Value;
                    String password = context.Request.Cookies["password"].Value;
                    user = new UserDal().Login(username, password);
                    SetSessionUser(context, user);
                }
                catch (Exception ex)
                {
                    Log.Debug(ex);
                }

                if(user == null)
                {
                    throw new IException("没有登录或登录失效");
                }

                return user;
            }
            else
            {
                return (UserModel)context.Session["user"];
            }

        }

        /// <summary>
        /// 设置用户对象到session中
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        protected void SetSessionUser(HttpContext context, UserModel user)
        {
            context.Session["user"] = user;
        }


        [Obsolete("方法已被弃用,请改用新方案", false)]
        /// <summary>
        /// 封装标准查询
        /// </summary>
        /// <param name="context"></param>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        protected T RequestQuery(HttpContext context, out int page, out int rows, ref DateTime startTime, ref DateTime endTime)
        {

            var bean = RequestBean(context);

            page = int.Parse(context.Request["page"] ?? "1");
            if (page < 1)
            {
                page = 1;
            }
            rows = int.Parse(context.Request["rows"] ?? "20");

            String tmp = context.Request["startTime"];
            if (!string.IsNullOrEmpty(tmp))
            {
                startTime = DateTime.Parse(tmp);
            }
            tmp = context.Request["endTime"];
            if (!string.IsNullOrEmpty(tmp))
            {
                endTime = DateTime.Parse(tmp);
            }

            return bean;
        }




        protected void OutPutMes(HttpContext context, string str)
        {
            context.Response.ContentType = "text/json";
            context.Response.Write(str);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }



    }
}